package com.kingschan.jeasytag.sql.query.mysql;

import java.io.Serializable;
import java.sql.Connection;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import org.apache.log4j.Logger;
import com.kingschan.jeasytag.enums.DbType;
import com.kingschan.jeasytag.sql.JdbcTemplete;
import com.kingschan.jeasytag.sql.query.Pagination;
import com.kingschan.jeasytag.sql.query.Query;
import com.kingschan.jeasytag.sql.sqlparse.GenericSelectParse;
import com.kingschan.util.lang.DateUtil;
/**
 * @author kingschan
 *date:2013-4-15
 */
public class MySqlDefaultQuery implements Query,Serializable{
	private static final long serialVersionUID = 1L;
	private static Logger log = Logger.getLogger(MySqlDefaultQuery.class);
	@Override
	public int getTotalRecordSQL(Connection con, String sql,Boolean closeConnection) throws Exception {	
		return JdbcTemplete.getTotalRows(con, sql, closeConnection);
	}

	@Override
	public Pagination paginationQuery(
			Connection con,
			String sql,
			int pageIndex,
			int pagesize,
			List<String> orderByStr,
			Boolean closeConnection,
			String whereStr) throws Exception {
		long executeDate = System.currentTimeMillis();
		Pagination p = new Pagination();
		List<Map<String, Object>> data= null;
		String count_sql =builderPaginationSQL(sql, 0, 0, orderByStr, whereStr, true, 0);
		int total=getTotalRecordSQL(con, count_sql, false);
		int limit_end=0;
		limit_end=pagesize>total?total:pagesize;
		String paginationSql=builderPaginationSQL(sql, pageIndex, limit_end, orderByStr, whereStr, false, total);
		log.debug(String.format("Execute Sql : %s", paginationSql));
		data=JdbcTemplete.getListBySql(con, paginationSql, closeConnection);
		p.setData(data);
		p.setEnd(limit_end);
		p.setStart((pageIndex-1)*pagesize);
		p.setSql(paginationSql);
		p.setTotal(total);		
		long finishDate=System.currentTimeMillis();
		log.info(String.format("Query Time :%s", DateUtil.runtimeDifference(finishDate-executeDate)));
		
		return p;
	}

	/**
	 *builderPaginationSQL
	 * @param sql 
	 * @param limit_start 
	 * @param limit_start 
	 * @param orderByStr 
	 * @param whereStr  
	 * @param groupBy   
	 * @param having   
	 * @param iscountSQL 
	 * @return
	 * @throws Exception 
	 */
	private String builderPaginationSQL(
			String sql,
			int limit_start,
			int limit_end,
			List<String> orderByStr,			
			String whereStr,
			Boolean iscountSQL,
			int total
	) throws Exception{
		GenericSelectParse sp = new GenericSelectParse(sql,DbType.MYSQL);		
		sp.appendWhere(whereStr);
		sp.setOrderby(orderByStr);
		
		if (iscountSQL) {
			List<String> lis = new ArrayList<String>();
			lis.add("count(*)");
			sp.setSelectItem(lis);
		}else{			
			sp.paginationLimit(limit_start, limit_end);
		}
		
		
		return sp.toString();
	}

}
